/**
 *******************************************************************************
 * @file  hc32f160_efm.h
 * @brief This file contains all the functions prototypes of the EFM driver
 *        library.
 @verbatim
   Change Logs:
   Date             Author          Notes
   2020-11-27       CDT             First version
 @endverbatim
 *******************************************************************************
 * Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
 *
 * This software component is licensed by HDSC under BSD 3-Clause license
 * (the "License"); You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                    opensource.org/licenses/BSD-3-Clause
 *
 *******************************************************************************
 */
#ifndef __HC32F160_EFM_H__
#define __HC32F160_EFM_H__

/* C binding of definitions if building with C++ compiler */
#ifdef __cplusplus
extern "C"
{
#endif

/*******************************************************************************
 * Include files
 ******************************************************************************/
#include "hc32_common.h"
#include "ddl_config.h"

/**
 * @addtogroup HC32F160_DDL_Driver
 * @{
 */

/**
 * @addtogroup DDL_EFM
 * @{
 */

#if (DDL_EFM_ENABLE == DDL_ON)

/*******************************************************************************
 * Global type definitions ('typedef')
 ******************************************************************************/
/**
 * @defgroup EFM_Global_Types EFM Global Types
 * @{
 */

/**
 * @brief EFM initialization structure
 */
typedef struct
{
    uint32_t            u32WaitCycle;   /*!< Specifies the efm read wait cycles.
                                            This parameter can be a value of @ref EFM_Wait_Cycle.              */

    uint32_t            u32Prefetch;    /*!< Specifies the prefetch on or off.
                                            This parameter can be a value of @ref EFM_Prefetch_Func.       */

    uint32_t            u32CancelErase; /*!< Specifies the Cancel the erase on or off.
                                            This parameter can be a value of @ref EFM_Cancel_Erase.       */

    uint32_t            u32BusStatus;   /*!< Specifies the bus status busy or release while program & erase.
                                            This parameter can be a value of @ref EFM_Bus_State.            */
} stc_efm_init_t;

/**
 * @brief EFM unique ID definition
 */
typedef struct
{
    uint32_t            u32UniqueID0;      /*!< unique ID 0.       */
    uint32_t            u32UniqueID1;      /*!< unique ID 1.       */
    uint32_t            u32UniqueID2;      /*!< unique ID 2.       */
} stc_efm_unique_id_t;

/**
 * @}
 */

/*******************************************************************************
 * Global pre-processor symbols/macros ('#define')
 ******************************************************************************/
/**
 * @defgroup EFM_Global_Macros EFM Global Macros
 * @{
 */

/**
 * @defgroup EFM_Address EFM address area
 * @{
 */
#define EFM_START_ADDR_1            (0x00000000UL) /*!< Flash start address 1 */
#define EFM_END_ADDR_1              (0X0003FFFFUL) /*!< Flash end address 1   */
#define EFM_START_ADDR_2            (0x01000800UL) /*!< Flash start address 2 */
#define EFM_END_ADDR_2              (0X01000BFFUL) /*!< Flash end address 2   */
/**
 * @}
 */

/**
 * @defgroup EFM_Cancel_Erase EFM Cancel Erase
 * @{
 */
#define EFM_CANCEL_ERASE_OFF        (0x00000000UL)    /*!< Disable Flash cancel sector erase */
#define EFM_CANCEL_ERASE_ON         (EFM_FWMC_ERCALE) /*!< Enable Flash cancel sector erase */
/**
 * @}
 */

/**
 * @defgroup EFM_Wait_Cycle EFM Wait Cycle
 * @{
 */
#define EFM_WAIT_CYCLE0              (0x00000000UL) /*!< Don't insert read wait cycle */
#define EFM_WAIT_CYCLE1              (0x00000001UL) /*!< Insert 1 read wait cycles */
#define EFM_WAIT_CYCLE2              (0x00000002UL) /*!< Insert 2 read wait cycles */
#define EFM_WAIT_CYCLE3              (0x00000003UL) /*!< Insert 3 read wait cycles */
/**
 * @}
 */

/**
 * @defgroup EFM_Prefetch_Func EFM Prefetch function
 * @{
 */
#define EFM_PREFETCH_ON              (EFM_FRMC_PREFETE) /*!< Enable prefetch function */
#define EFM_PREFETCH_OFF             (0x0UL)            /*!< Disable prefetch function */
/**
 * @}
 */

/**
 * @defgroup EFM_Bus_State EFM Bus state while flash program or erase
 * @{
 */
#define EFM_BUS_BUSY               (0x00000000UL)       /*!< Bus busy while flash program or erase */
#define EFM_BUS_RELEASE            (EFM_FWMC_BUSHLDCTL) /*!< Bus release while flash program or erase */
/**
 * @}
 */

/**
 * @defgroup EFM_Mode_definition EFM program or erase mode definition
 * @{
 */
#define EFM_MD_PGM_SINGLE          (0x00000010UL)       /*!< Program single mode */
#define EFM_MD_PGM_READBACK        (0x00000020UL)       /*!< Program and read back mode */
#define EFM_MD_PGM_SEQ             (0x00000030UL)       /*!< Program sequence mode */
#define EFM_MD_ERASE_SECT          (0x00000040UL)       /*!< Sector erase */
#define EFM_MD_ERASE_CHIP          (0x00000050UL)       /*!< Chip erase */
#define EFM_MD_READONLY            (0x00000000UL)       /*!< Read only */
/**
 * @}
 */

/**
 * @defgroup EFM_Flag_definition EFM Flag definition
 * @{
 */
#define EFM_FLAG_PEWERR            (EFM_FSR_PEWERR)     /*!< EFM Programming/erase error flag.              */
#define EFM_FLAG_PEPRTERR          (EFM_FSR_PEPRTERR)   /*!< EFM Programming/erase protect area error flag. */
#define EFM_FLAG_PGMISMTCHERR      (EFM_FSR_PGMISMTCH)  /*!< EFM Programming miss match error flag          */
#define EFM_FLAG_OPTEND            (EFM_FSR_OPTEND)     /*!< EFM End of operation flag.                     */
#define EFM_FLAG_COLERR            (EFM_FSR_COLERR)     /*!< EFM Read collide error flag.                   */
#define EFM_FLAG_ERCAL             (EFM_FSR_ERCAL)      /*!< EFM sector erase cancel flag.                  */
#define EFM_FLAG_RDY               (EFM_FSR_RDY)        /*!< EFM ready flag.                                */
/**
 * @}
 */

/**
 * @defgroup EFM_Interrupt_definition EFM Interrupt definition
 * @{
 */
#define EFM_INT_EOP                (EFM_FITE_OPTENDITE)      /*!< End of EFM operation Interrupt      */
#define EFM_INT_PEERR              (EFM_FITE_PEERRITE)       /*!< Program/erase error Interrupt       */
#define EFM_INT_RDCOLERR           (EFM_FITE_COLERRITE)      /*!< Read collide error Interrupt        */
/**
 * @}
 */

/**
 * @defgroup EFM_Keys EFM Keys
 * @{
 */
#define EFM_KEY1                    (0x00000123UL)
#define EFM_KEY2                    (0x00003210UL)
/**
 * @}
 */

/**
 * @}
 */

/*******************************************************************************
 * Global variable definitions ('extern')
 ******************************************************************************/

/*******************************************************************************
  Global function prototypes (definition in C source)
 ******************************************************************************/
/**
 * @addtogroup EFM_Global_Functions
 * @{
 */

/**
 * @brief  EFM Protect Unlock.
 * @param  None
 * @retval None
 */
__STATIC_INLINE void EFM_Unlock(void)
{
    WRITE_REG32(CM_EFM->FAPRT, EFM_KEY1);
    WRITE_REG32(CM_EFM->FAPRT, EFM_KEY2);
}

/**
 * @brief  EFM Protect Lock.
 * @param  None
 * @retval None
 */
__STATIC_INLINE void EFM_Lock(void)
{
    WRITE_REG32(CM_EFM->FAPRT, 0x0000ABCDUL);
}

void EFM_Cmd(en_functional_state_t enNewState);
void EFM_SetWaitCycle(uint32_t u32WaitCycle);
void EFM_SetBusStatus(uint32_t u32Status);
void EFM_PrefetchCmd(en_functional_state_t enNewState);
void EFM_IntCmd(uint32_t u32EfmInt, en_functional_state_t enNewState);
void EFM_ClearStatus(uint32_t u32Flag);
void EFM_SetWindowProtectAddr(uint32_t u32StartAddr, uint32_t u32EndAddr);
void EFM_CancelSectorErase(uint32_t u32CancelErase);

en_result_t EFM_StructInit(stc_efm_init_t *pstcEfmInit);
en_result_t EFM_Init(const stc_efm_init_t *pstcEfmInit);
en_result_t EFM_Program32(uint32_t u32Addr, uint32_t u32Data);
en_result_t EFM_Program16(uint32_t u32Addr, uint16_t u16Data);
en_result_t EFM_Program8(uint32_t u32Addr, uint8_t u8Data);
en_result_t EFM_ProgramReadBack32(uint32_t u32Addr, uint32_t u32Data);
en_result_t EFM_ProgramReadBack16(uint32_t u32Addr, uint16_t u16Data);
en_result_t EFM_ProgramReadBack8(uint32_t u32Addr, uint8_t u8Data);
en_result_t EFM_SeqProgram32(uint32_t u32Addr, uint32_t u32Len, const uint32_t *pu32Buf);
en_result_t EFM_SeqProgram16(uint32_t u32Addr, uint32_t u32Len, const uint16_t *pu16Buf);
en_result_t EFM_SeqProgram8(uint32_t u32Addr, uint32_t u32Len, const uint8_t *pu8Buf);
en_result_t EFM_SectorErase(uint32_t u32Addr);
en_result_t EFM_ChipErase(void);
en_result_t EFM_SetOperateMode(uint32_t u32Mode);

en_flag_status_t EFM_GetStatus(uint32_t u32Flag);
en_result_t EFM_GetUID(stc_efm_unique_id_t *stcUID);
/**
 * @}
 */

#endif /* DDL_EFM_ENABLE */

/**
 * @}
 */

/**
 * @}
 */

#ifdef __cplusplus
}
#endif

#endif /* __HC32F160_EFM_H__ */

/*******************************************************************************
 * EOF (not truncated)
 ******************************************************************************/
